import { EActionCode } from "framework/FSM/Action/ActionCode";
import { cpu_used } from "utils/decorate/decorate";

export abstract class ActionBase<T extends Action> implements IActionExecute<T>
{
    abstract execute(action: T): ActionCode;
}

export abstract class ActionBaseOfCreep<T extends IActionCMD<keyof ICreepActions>> implements ActionBase<T>
{
    /**
     * 
     * @param action 
     * @returns OK 继续下一步的执行，FAILED 终止执行 并且清理Action
     */
   
    protected   updateArgs(action: T): ActionCode 
    {
        if(Game.creeps[action.arg.entity.name])
        {
            action.arg.entity = Game.creeps[action.arg.entity.name];
            return  EActionCode.OK;
        }else if(Game.powerCreeps[action.arg.entity.name])
        {
            action.arg.entity = Game.powerCreeps[action.arg.entity.name];
            return  EActionCode.OK;
        }
        return EActionCode.FAILED;
    }
    protected concatLog(output:{text:string,type:string},...arg:any[]):void
    {
        const tmp = arg.join(`_`);
        output.text+=`\t`+tmp;
        
    }
    protected abstract _execute(action: T): ActionCode;
    @cpu_used((action:any)=>{
        return `${action.arg.entity.GUID()}-${action.key}`
    },
    (action:any,cpu:number)=>
    {
        return action.arg.entity.entityType()=="Creep" && cpu>1
    },
    (log:string,action:any)=>
    {
        action.arg.entity.log('info',action.key,log);
    },
    )
    public execute(action: T): ActionCode
    {
       
        const cpu1 = Game.cpu.getUsed();
        if(this.updateArgs(action)== OK)
        {
            // if(action.ttl == 0)
            // {
            //     return EActionCode.OK;
            // }
            // else if(action.ttl>0)
            // {
            //     action.ttl--;
            // }
            if(action.isExpired && action.isExpired(action) )
            {
                const cpu2 = Game.cpu.getUsed();
                //action.arg.entity.log('info',`${cpu2-cpu1}`,'Action已经失效',action.key);
                return EActionCode.OK;
            }
            
            const ret  =  this._execute(action);
            const cpu3 = Game.cpu.getUsed();
            //action.arg.entity.log('info',action.key,`${cpu3 - cpu1}`,ret);
            return ret;
        }
        else 
        {
            return EActionCode.FAILED;
        }
    }
}